#include "Socks5Server.h"

HANDLE Socks5Server::m_hInstance = NULL;

Socks5Server::Socks5Server(INT port)
:m_listeningPort(port),
Socket()
{
	sockaddr_in sa;

	memset(&sa, 0, sizeof(sa));

	sa.sin_family = PF_INET;    
	//sa.sin_addr.S_addr = INADDR_ANY;
	sa.sin_port = htons(m_listeningPort);          
	
	/* bind the socket to the internet address */
	if (bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR) {
		closesocket(s_);
		throw "Socket binding error";
	}

	if (listen(s_, DEFAULT_MAX_SIMULTANEOUS_CONNECTIONS)  == SOCKET_ERROR) {
		closesocket(s_);
		throw "Socket listening error";
	}
}

Socks5Server::~Socks5Server()
{

}

Socks5Server* Socks5Server::GetInstance(INT port /* = DEFAULT_LISTENING_PORT */)
{
	if (NULL == m_hInstance)
	{
		m_hInstance = new Socks5Server(port);
	}
	return (Socks5Server*)m_hInstance;
}

Socket* Socks5Server::Accept()
{
	sockaddr new_addr;
	SOCKET new_sock = accept(s_, &new_addr, 0);
	if (new_sock == INVALID_SOCKET) {
		int rc = WSAGetLastError();
		if(rc==WSAEWOULDBLOCK) {
			return NULL; // non-blocking call, no request pending
		}
		else {
			throw "Invalid Socket";
		}
	}

	Socket* r = new Socket(new_sock, NULL, &new_addr);
	return r;
}
